package com.crrc.dataparse.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.crrc.dataparse.base.exception.Error;
import com.crrc.dataparse.base.exception.RSPException;
import com.crrc.dataparse.base.log.LogConstant;
import com.crrc.dataparse.base.log.LogRecord;
import com.crrc.dataparse.config.ParseConfig;
import com.crrc.dataparse.entity.*;
import com.crrc.dataparse.parse.PostAlg.MFPost;
import com.crrc.dataparse.parse.PostAlg.SFPost;
import com.crrc.dataparse.parse.TemplateAlg.MFTemp;
import com.crrc.dataparse.parse.TemplateAlg.SFTemp;
import com.crrc.dataparse.templatepara.IDataTrans;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
@Component
public class DataDecode{
    @Autowired
    private PaserInfo paserInfo;
    @Autowired
    private ParseConfig parseConfig;

    /**
     * 单频率整包
     * @param rawData: 解析前数据
     * @return 解析后数据
     * @author XinXin
     * @date 2025/8/14 22:36
     */

    public JSONObject calc_sf(String rawData) throws Exception {
        try {
            Protocol protocol = paserInfo.getProtocol();
            ParsedResult resPdp = new ParsedResult();
            SFPost postAlg = new SFPost();
            //解析数据包头
            int offset = postAlg.parseProtocolHead(rawData, paserInfo.getProtocol(), resPdp, paserInfo);

            Template template = postAlg.getTemplate(rawData, paserInfo, protocol);
            SFTemp tempAlg = new SFTemp();
            tempAlg.templateParse(rawData, offset, template, paserInfo, resPdp);
            //数据转换
            transformTempValue_SF(resPdp, paserInfo.getTempParaMap());
            postAlg.postProcess_sf(resPdp);
            return resPdp.toJson_SF(parseConfig.getTrain_field(), parseConfig.getLine_field(), parseConfig.getDevice_field(), parseConfig.getTime_field(), parseConfig.getData_field(),parseConfig.getDevice(),parseConfig.getTrain_type_field());
        } catch (Exception e) {
            e.printStackTrace(System.out);
            return null;
        }
    }

    /**
     * 多频率整包
     * @param rawData: 解析前数据
     * @return 解析后数据
     * @author XinXin
     * @date 2025/8/14 22:36
     */

    public JSONObject calc_mf(String rawData) throws Exception {
        try {
            Protocol protocol = paserInfo.getProtocol();
            ParsedResult resPdp = new ParsedResult();
            MFPost postAlg = new MFPost();
            //解析数据包头
            int offset = postAlg.parseProtocolHead(rawData, paserInfo.getProtocol(), resPdp, paserInfo);

            Template template = postAlg.getTemplate(rawData, paserInfo, protocol);
            MFTemp tempAlg = new MFTemp();
            tempAlg.templateParse(rawData, offset, template, paserInfo, resPdp);
            //数据转换
            transformTempValue_MF(resPdp, paserInfo.getTempParaMap());
            postAlg.postProcess_mf(resPdp);
            return resPdp.toJson(parseConfig.getTrain_field(), parseConfig.getLine_field(), parseConfig.getDevice_field(), parseConfig.getTime_field(), parseConfig.getData_field(),parseConfig.getDevice(),parseConfig.getTrain_type_field());
        } catch (Exception e) {
            e.printStackTrace(System.out);
            return null;
        }
    }

    /**
     * 单频率多个小包合一
     * @param rawData: 解析前数据
     * @return 解析后数据
     * @author XinXin
     * @date 2025/8/14 22:36
     */

    public JSONArray calc_sf_mp(String rawData) throws Exception {
        try {
            JSONArray resultArray = new JSONArray();
            Protocol protocol = paserInfo.getProtocol();
            ParsedResult resPdp = new ParsedResult();
            SFPost postAlg = new SFPost();
            int offset = postAlg.parseProtocolHead(rawData, paserInfo.getProtocol(), resPdp, paserInfo);
            Template template = postAlg.getTemplate(rawData, paserInfo, protocol);
            for (int i = 0; i < parseConfig.getPackage_num(); i++) {
                SFTemp tempAlg = new SFTemp();
                offset = tempAlg.templateParse(rawData, offset, template, paserInfo, resPdp);
                //数据转换
                if (i==0){
                    transformTempValue_SF_MP_HEAD(resPdp, paserInfo.getTempParaMap());
                    postAlg.postProcess_sf(resPdp);
                }else {
                    Integer increateTime = Integer.valueOf(parseConfig.getIncreate_time()) * i;
                    postAlg.postProcess_mp(resPdp, increateTime);
                }
                transformTempValue_SF_MP_DATA(resPdp, paserInfo.getTempParaMap());
                resultArray.add(resPdp.toJson_SF(parseConfig.getTrain_field(), parseConfig.getLine_field(), parseConfig.getDevice_field(), parseConfig.getTime_field(), parseConfig.getData_field(),parseConfig.getDevice(),parseConfig.getTrain_type_field()));
            }
            return resultArray;
        } catch (Exception e) {
            e.printStackTrace(System.out);
            return null;
        }
    }

    /**
     * 多频率多个小包合一
     * @param rawData: 解析前数据
     * @return 解析后数据
     * @author XinXin
     * @date 2025/8/14 22:36
     */

    public JSONArray calc_mf_mp(String rawData) throws Exception {
        try {
            JSONArray resultArray = new JSONArray();
            Protocol protocol = paserInfo.getProtocol();
            ParsedResult resPdp = new ParsedResult();
            MFPost postAlg = new MFPost();
            int offset = postAlg.parseProtocolHead(rawData, paserInfo.getProtocol(), resPdp, paserInfo);
            Template template = postAlg.getTemplate(rawData, paserInfo, protocol);
            for (int i = 0; i < parseConfig.getPackage_num(); i++) {
                MFTemp tempAlg = new MFTemp();
                offset = tempAlg.templateParse(rawData, offset, template, paserInfo, resPdp);
                //数据转换
                if (i==0){
                    transformTempValue_MF_MP_HEAD(resPdp, paserInfo.getTempParaMap());
                    postAlg.postProcess_mf(resPdp);
                }else {
                    Integer increateTime = Integer.valueOf(parseConfig.getIncreate_time()) * i;
                    postAlg.postProcess_mp(resPdp, increateTime);
                }
                transformTempValue_MF_MP_DATA(resPdp, paserInfo.getTempParaMap());
                resultArray.add(resPdp.toJson(parseConfig.getTrain_field(), parseConfig.getLine_field(), parseConfig.getDevice_field(), parseConfig.getTime_field(), parseConfig.getData_field(),parseConfig.getDevice(),parseConfig.getTrain_type_field()));
            }
            return resultArray;
        } catch (Exception e) {
            e.printStackTrace(System.out);
            return null;
        }
    }
    /**
     * 解析高频属性值
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_MF(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception{
        Iterator<?> iter = pdp.getBaseInfoMapIter();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
            TemplatePara para = paraIdToPara.get(entry.getKey());
            String value = transValue(entry.getKey(), entry.getValue(), para);
            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addBaseInfo(entry.getKey(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:" + entry.getKey() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值" + para.getParameterName() + "," + entry.getKey());
                iter.remove();
            }
        }
        iter = pdp.getWorkStatusMapIter();
        while (iter.hasNext()) {
            ParsedResult.WorkStatusRecord entry = (ParsedResult.WorkStatusRecord) iter.next();
            String paraId = entry.getWorkStatusId();
            if(entry.getWorkStatusId().contains(".")){
                paraId = entry.getWorkStatusId().split("\\.")[1];
            }

            TemplatePara para = paraIdToPara.get(paraId);
            //LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " );

            String value = transValue(paraId, entry.getValue(), para);

            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addWorkStatus(entry.getWorkStatusId(), entry.getTime(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值：" + para.getParameterName() + "," + entry.getWorkStatusId());
                iter.remove();
            }

        }
        return pdp;
    }

    /**
     * 解析单频率属性值
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_SF(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception{
        Iterator<?> iter = pdp.getBaseInfoMapIter();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
            TemplatePara para = paraIdToPara.get(entry.getKey());
            String value = transValue(entry.getKey(), entry.getValue(), para);
            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addBaseInfo(entry.getKey(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:" + entry.getKey() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值" + para.getParameterName() + "," + entry.getKey());
                iter.remove();
            }
        }
        iter = pdp.getSFWorkStatusMapIter_SF();
        while (iter.hasNext()) {
            ParsedResult.WorkStatusRecord entry = (ParsedResult.WorkStatusRecord) iter.next();
            String paraId = entry.getWorkStatusId();
            if(entry.getWorkStatusId().contains(".")){
                paraId = entry.getWorkStatusId().split("\\.")[1];
            }

            TemplatePara para = paraIdToPara.get(paraId);
            //LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " );

            String value = transValue(paraId, entry.getValue(), para);

            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addSFWorkStatus(entry.getWorkStatusId(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值：" + para.getParameterName() + "," + entry.getWorkStatusId());
                iter.remove();
            }

        }
        return pdp;
    }


    /**
     * 解析单频率多包包头
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_SF_MP_HEAD(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception {
        Iterator<?> iter = pdp.getBaseInfoMapIter();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
            TemplatePara para = paraIdToPara.get(entry.getKey());
            String value = transValue(entry.getKey(), entry.getValue(), para);
            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addBaseInfo(entry.getKey(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:" + entry.getKey() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值" + para.getParameterName() + "," + entry.getKey());
                iter.remove();
            }
        }
        return pdp;
    }
    /**
     * 解析单频率多包数据体
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_SF_MP_DATA(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception{
        Iterator<?> iter = pdp.getSFWorkStatusMapIter_SF();
        while (iter.hasNext()) {
            ParsedResult.WorkStatusRecord entry = (ParsedResult.WorkStatusRecord) iter.next();
            String paraId = entry.getWorkStatusId();
            if(entry.getWorkStatusId().contains(".")){
                paraId = entry.getWorkStatusId().split("\\.")[1];
            }

            TemplatePara para = paraIdToPara.get(paraId);
            //LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " );

            String value = transValue(paraId, entry.getValue(), para);

            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addSFWorkStatus(entry.getWorkStatusId(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值：" + para.getParameterName() + "," + entry.getWorkStatusId());
                iter.remove();
            }

        }
        return pdp;
    }

    /**
     * 解析多频率多包包头
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_MF_MP_HEAD(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception {
        Iterator<?> iter = pdp.getBaseInfoMapIter();
        while (iter.hasNext()) {
            Map.Entry<String, String> entry = (Map.Entry<String, String>) iter.next();
            TemplatePara para = paraIdToPara.get(entry.getKey());
            String value = transValue(entry.getKey(), entry.getValue(), para);
            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addBaseInfo(entry.getKey(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:" + entry.getKey() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值" + para.getParameterName() + "," + entry.getKey());
                iter.remove();
            }
        }
        return pdp;
    }
    /**
     * 解析多频率多包数据体
     * @param pdp: 解析后数据包
     * @param paraIdToPara: 模板参数Map
     * @return 数据转换后的解析数据包
     * @author XinXin
     * @date 2025/08/15 22:47
     */
    public ParsedResult transformTempValue_MF_MP_DATA(ParsedResult pdp, Map<String, TemplatePara> paraIdToPara) throws Exception{
        Iterator<?> iter = pdp.getWorkStatusMapIter();
        while (iter.hasNext()) {
            ParsedResult.WorkStatusRecord entry = (ParsedResult.WorkStatusRecord) iter.next();
            String paraId = entry.getWorkStatusId();
            if(entry.getWorkStatusId().contains(".")){
                paraId = entry.getWorkStatusId().split("\\.")[1];
            }

            TemplatePara para = paraIdToPara.get(paraId);
            //LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " );

            String value = transValue(paraId, entry.getValue(), para);

            // 用转换后的值替换原有的值
            if (value != null) {
                pdp.addWorkStatus(entry.getWorkStatusId(), entry.getTime(), value);
                LogRecord.debug(LogConstant.LOG_FLAG_TRANS + para.getParameterName() + "：key:"+ entry.getWorkStatusId() + " = " + value);
            } else {
                LogRecord.debug("数据转换后为空的值：" + para.getParameterName() + "," + entry.getWorkStatusId());
                iter.remove();
            }

        }
        return pdp;
    }

    /**
     * 对一个具体模板参数数据进行数据转换
     *
     */
    private String transValue(String key, String value, TemplatePara para) throws Exception {
        if (para == null) {
            throw new RSPException(LogConstant.LOG_FLAG_TRANS + "数据转换错误，模板参数不存在", Error.ExceptionType.ITEM_MISSING, false);
        }

        // 获取参数处理方案
        List<TPara2Treat> treatList = para.gettPara2TreatList();
        if (treatList.get(0).getParaTreatClass() == null || treatList.size() == 0) { // 无处理方案
            return value;
        }

        // 执行处理方案
        for (TPara2Treat tPara2Treat : treatList) {
            ParaTreatClass ptc = tPara2Treat.getParaTreatClass();
            String className = ptc.getClassName();
            try {
                Class.forName(className);
            }
            catch (Exception e) {
                throw e;
            }
            IDataTrans dataTranser = (IDataTrans) Class.forName(className).newInstance();
            value = dataTranser.trans(value, para.getResolution(), para.getOffset());
        }
        return value;
    }
}
